#include <p33fxxxx.h>
#include <timer.h>
#include <adc.h>
#include	"APP026-3_LCM.h"

/* Configuration Settings */
// OSC Input = Internal FRC
// Debug Interface PGEC1, PGED1, Disable JTAG
// Disabld WDT, Clock Switch, Fail Safe Clock Monitor ,IO One Way.
// Power-On Reset 128ms, Enable BOR.
// PWM pins module controllered by PORT.
// PWM module high side output pins have active-high output polarity

_FOSCSEL( FNOSC_FRC & IESO_OFF ); 
_FOSC( POSCMD_HS & OSCIOFNC_OFF & IOL1WAY_OFF & FCKSM_CSECMD );
_FICD( ICS_PGD1 & JTAGEN_OFF );
_FWDT( WDTPOST_PS32768 & WDTPRE_PR128 & WINDIS_OFF & FWDTEN_OFF );
_FPOR( FPWRT_PWR128 & LPOL_ON & HPOL_ON & ALTI2C_OFF & PWMPIN_ON );

#define SystemFrequency 40000000L
#define Timer1Tick ( ( SystemFrequency / 256 ) / Timer1TogglesPerSec )
#define Timer1TogglesPerSec 10

const unsigned char LCMString1[ ] = "dsPIC33FJxxMC804"; 
const unsigned char LCMString2[ ] = "AD:"; 
unsigned int VR1Value = 0;

void __attribute__((interrupt , no_auto_psv )) _T1Interrupt( void )
{
	IFS0bits.T1IF = 0;

	ConvertADC1( );
}
// PWM module low side output pins have active-high output polarity

int main( void )
{
	// FREF = Crystal / 2 = 8M Hz / 2 = 4M Hz
	CLKDIVbits.PLLPRE = 0;

	// FVOC = FREF * 40( 38 + 2 ) = 4M Hz * 40 = 160M Hz
	PLLFBDbits.PLLDIV = 38;

	// FOSC = FVOC / 2 = 160M Hz / 2 = 80M Hz
	CLKDIVbits.PLLPOST = 0;

	// Initiate Clock Switch to Primary Oscillator with PLL (NOSC = 0b011 )
	__builtin_write_OSCCONH( 0x03 );
	__builtin_write_OSCCONL( 0x01 );

	// Wait for Clock switch to occur
	while( OSCCONbits.COSC != 0b011 );

	// Wait for PLL to lock
	while( !OSCCONbits.LOCK );

	TRISBbits.TRISB5 = 0;

	LCM_Init( );

	LCM_SetCursor( 0 , 0 );
	LCM_PutROMString( LCMString1 );
	LCM_SetCursor( 0 , 1 );
	LCM_PutROMString( LCMString2 );

	OpenTimer1( T1_ON & T1_IDLE_CON & T1_GATE_OFF & T1_PS_1_256 & T1_SYNC_EXT_OFF & T1_SOURCE_INT , Timer1Tick );
	ConfigIntTimer1( T1_INT_ON & T1_INT_PRIOR_4 );

	OpenADC1( ADC_MODULE_ON & ADC_IDLE_CONTINUE & ADC_ADDMABM_SCATTR & ADC_AD12B_10BIT & ADC_FORMAT_INTG &
			  ADC_CLK_MANUAL & ADC_AUTO_SAMPLING_ON & ADC_MULTIPLE & ADC_SAMP_ON ,
			  ADC_VREF_AVDD_AVSS & ADC_SCAN_OFF & ADC_SELECT_CHAN_0 & ADC_DMA_ADD_INC_1 &
			  ADC_ALT_BUF_OFF & ADC_ALT_INPUT_OFF ,
			  ADC_SAMPLE_TIME_31 & ADC_CONV_CLK_INTERNAL_RC & ADC_CONV_CLK_256Tcy ,
			  ADC_DMA_BUF_LOC_1 ,
			  ENABLE_AN1_ANA , 0x00 ,
			  SCAN_NONE_16_31 , SCAN_NONE_0_15 );

	SetChanADC1( ADC_CH123_POS_SAMPLEA_0_1_2 & ADC_CH123_NEG_SAMPLEA_VREFN &
				 ADC_CH123_POS_SAMPLEB_0_1_2 & ADC_CH123_NEG_SAMPLEB_VREFN ,
				 ADC_CH0_POS_SAMPLEA_AN1 & ADC_CH0_NEG_SAMPLEA_VREFN &
				 ADC_CH0_POS_SAMPLEB_AN0 & ADC_CH0_NEG_SAMPLEB_VREFN );

	while( 1 )
	{	
		if( IFS0bits.AD1IF )
		{
			IFS0bits.AD1IF = 0;

			VR1Value = ( unsigned int ) ReadADC1( 0 );

			LCM_SetCursor( 0 , 1 );
			LCM_PutROMString( LCMString2 );
			LCM_PutNumber( VR1Value , 4 );
		
			LATBbits.LATB5 = !LATBbits.LATB5;
		}
	}	

	while( 1 );
}
